package com.wejoy.video.middle.station.data.service.workorder.impl;

import com.wejoy.video.middle.station.data.domain.system.SysBaseParam;
import com.wejoy.video.middle.station.data.domain.system.SysNotice;
import com.wejoy.video.middle.station.data.domain.system.SysUser;
import com.wejoy.video.middle.station.data.domain.workorder.WorkOrderInfo;
import com.wejoy.video.middle.station.data.enums.dict.*;
import com.wejoy.video.middle.station.data.exception.BusinessException;
import com.wejoy.video.middle.station.data.mapper.workorder.IWorkOrderInfoMapper;
import com.wejoy.video.middle.station.data.service.common.IIdWorkerService;
import com.wejoy.video.middle.station.data.service.system.ISysBaseParamService;
import com.wejoy.video.middle.station.data.service.system.ISysNoticeService;
import com.wejoy.video.middle.station.data.service.workorder.IWorkOrderInfoService;
import com.wejoy.video.middle.station.data.util.DateUtils;
import com.wejoy.video.middle.station.data.util.WJAssert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 工单主表
 *
 * @author miracle_j
 * @date 2022年11月16日 17:28:50
 */
@Service
@Transactional
public class WorkOrderInfoServiceImpl implements IWorkOrderInfoService {
    @Autowired
    private IWorkOrderInfoMapper workOrderInfoMapper;
    @Autowired
    private IIdWorkerService idWorkerService;
    @Autowired
    private ISysNoticeService sysNoticeService;
    @Autowired
    private ISysBaseParamService sysBaseParamService;

    @Override
    public void save(WorkOrderInfo req, String operator) {
        req.setOperator(operator);
        if (null == req.getId()) {
            insertSelective(req);
        } else {
            updateSelectiveById(req);
        }
    }

    @Override
    public int insertSelective(WorkOrderInfo req) {
        req.setId(idWorkerService.getNextId());
        req.setStatus(EnumStatus.NEW.getCode());
        checkStringLength(req, false);
        return workOrderInfoMapper.insertSelective(req);
    }

    @Override
    public int updateSelectiveById(WorkOrderInfo workOrderInfo) {
        WJAssert.notNull(workOrderInfo, "入参对象不能为空");
        WJAssert.notNull(workOrderInfo.getId(), "id参数错误");
        WorkOrderInfo where = new WorkOrderInfo();
        where.setId(workOrderInfo.getId());
        return workOrderInfoMapper.updateSelective(workOrderInfo, where);
    }

    @Override
    public int getCount(WorkOrderInfo workOrderInfo) {
        return workOrderInfoMapper.getCount(workOrderInfo);
    }

    @Override
    public int getDataPermissionCount(WorkOrderInfo workOrderInfo) {
        checkStringLength(workOrderInfo, true);
        return workOrderInfoMapper.getDataPermissionCount(workOrderInfo);
    }

    @Override
    public WorkOrderInfo getOneById(Long id) {
        WJAssert.notNull(id, "id参数错误");
        WorkOrderInfo where = new WorkOrderInfo();
        where.setId(id);
        return workOrderInfoMapper.getOne(where);
    }

    @Override
    public void acceptOrder(Long id, SysUser loginSysUser) {
        WorkOrderInfo workOrderInfoDB = getOneById(id);
        if(ObjectUtils.isEmpty(workOrderInfoDB)){
            throw new BusinessException("ID 不合法");
        }
        if(!workOrderInfoDB.getOrderStatus().equals( EnumWorkOrderStatus.AGENCY.getCode())){
            throw new BusinessException("此工单已经被接单！");
        }
        workOrderInfoDB.setAcceptTime(new Date());
        workOrderInfoDB.setAcceptUserId(loginSysUser.getId());
        workOrderInfoDB.setAcceptUserName(loginSysUser.getName());
        workOrderInfoDB.setAcceptUserPhone(Long.valueOf(loginSysUser.getTel()));
        workOrderInfoDB.setOrderStatus(EnumWorkOrderStatus.ACCEPT_UNPROCESSED.getCode());
        WorkOrderInfo where = new WorkOrderInfo();
        where.setId(workOrderInfoDB.getId());
        where.setVersion(workOrderInfoDB.getVersion());
        workOrderInfoDB.setVersion(workOrderInfoDB.getVersion()+1);
        workOrderInfoDB.setOperator(loginSysUser.getName());
        int a = workOrderInfoMapper.updateSelective(workOrderInfoDB, where);
        if(a==0){
            throw new BusinessException("此工单已经被接单！");
        }
        String[] split = workOrderInfoDB.getManagerUserId().split(",");
        for (int i = 0; i < split.length; i++) {
            SysNotice sysNotice = new SysNotice();
            sysNotice.setIsRead(EnumReadNoticeType.HAVE_READ.getCode());
            sysNotice.setRemindType(EnumNoticePopUpsType.WARN_POPUPS.getCode());
            sysNotice.setIsRemind(EnumNoticeRemindtype.NOT_REMINDED.getCode());
            sysNotice.setType(EnumNoticeType.ACCEPT_ORDER_NOTICE.getCode());
            sysNotice.setToId(Long.valueOf(split[i]));
            sysNotice.setTitle(EnumNoticeType.ACCEPT_ORDER_NOTICE.getText());
            sysNotice.setContent(workOrderInfoDB.getDeptName()+"-"+workOrderInfoDB.getAlarmLocation());
            sysNotice.setOrderId(workOrderInfoDB.getId());
            sysNoticeService.save(sysNotice,"系统通知");
        }
    }

    @Override
    public List<WorkOrderInfo> getList(WorkOrderInfo workOrderInfo) {
        checkStringLength(workOrderInfo, true);
        return workOrderInfoMapper.getList(workOrderInfo);
    }

    @Override
    public WorkOrderInfo getOneByEventId(String eventId) {
        WJAssert.notNull(eventId, "id参数错误");
        WorkOrderInfo where = new WorkOrderInfo();
        where.setEventId(eventId);
        return workOrderInfoMapper.getOne(where);
    }

    @Override
    public List<WorkOrderInfo> getPageList(WorkOrderInfo workOrderInfo) {
        checkStringLength(workOrderInfo, true);
        return workOrderInfoMapper.getPageList(workOrderInfo);
    }

    @Override
    public List<WorkOrderInfo> getDataPermissionPageList(WorkOrderInfo workOrderInfo) {
        checkStringLength(workOrderInfo, true);
        return workOrderInfoMapper.getDataPermissionPageList(workOrderInfo);
    }

    @Override
    public void audit(Long id, String operator) {
        WorkOrderInfo req = new WorkOrderInfo();
        req.setId(id);
        req.setOperator(operator);
        req.setStatus(EnumStatus.AUDIT.getCode());
        updateSelectiveById(req);
    }

    @Override
    public void unaudit(Long id, String operator) {
        WorkOrderInfo req = new WorkOrderInfo();
        req.setId(id);
        req.setOperator(operator);
        req.setStatus(EnumStatus.NEW.getCode());
        updateSelectiveById(req);
    }

    @Override
    public void delete(Long id, String operator) {
        WorkOrderInfo req = new WorkOrderInfo();
        req.setId(id);
        req.setOperator(operator);
        req.setStatus(EnumStatus.DEL.getCode());
        updateSelectiveById(req);
    }

    @Override
    public boolean canItBeUrged(Long id,Long operatorId) {
        SysBaseParam interval = sysBaseParamService.getOneByUniCode("REMINDER_INTERVAL");
        if(ObjectUtils.isEmpty(interval)){
            return true;
        }
        String[] split = interval.getValue().split(",");
        SysNotice where = new SysNotice();
        where.setOrderId(id);
        where.setFromId(operatorId);
        where.setPageSize(1);
        where.setPageNo(1);
        List<SysNotice> list = sysNoticeService.getPageList(where);
        //查询最近的一条催单记录，判断是否可以催单
        for (SysNotice sysNotice : list) {
            try {
                Field f = Calendar.class.getField(split[1]);
                Integer v = (Integer) f.get(null);
                return DateUtils.minusTime(sysNotice.getCreateTime(), new Date(), v) >=Integer.parseInt(split[0]);
            } catch (NoSuchFieldException e) {
                throw new BusinessException("请检查基础参数配置！");
            } catch (IllegalAccessException e) {
                throw new BusinessException("请检查基础参数配置！");
            }
        }
        return true;
    }

    @Override
    public void reminders(Long id, String operator,Long operatorId) {
        WorkOrderInfo workOrderInfo = getOneById(id);
        if(workOrderInfo.getOrderStatus().equals(EnumWorkOrderStatus.AGENCY.getCode())){
            throw new BusinessException("未接单工单不能催单");
        }
        if(workOrderInfo.getOrderStatus().equals(EnumWorkOrderStatus.FINISHED.getCode())){
            throw new BusinessException("工单已完结");
        }
        SysNotice sysNoticeDB = new SysNotice();
        sysNoticeDB.setOrderId(id);
        sysNoticeDB.setIsRead(EnumReadNoticeType.HAVE_READ.getCode());
        sysNoticeDB.setTitle(EnumNoticeType.REMINDERS_NOTICE.getText());
        sysNoticeDB.setType(EnumNoticeType.REMINDERS_NOTICE.getCode());
        sysNoticeDB.setFromId(operatorId);
        sysNoticeDB.setToId(workOrderInfo.getAcceptUserId());
        sysNoticeDB.setContent(workOrderInfo.getDeptName()+","+workOrderInfo.getAlarmLocation());
        sysNoticeService.save(sysNoticeDB,operator);
    }

    /**
     * 参数校验注解默认使用的方法
     */
    private void checkStringLength(WorkOrderInfo workOrderInfo, boolean nullAble) {
        WJAssert.notNull(workOrderInfo, "入参对象不能为空");
        WJAssert.limitMaxLength(workOrderInfo.getManagerUserName(), true, 50, "负责人名称不合法!");
        WJAssert.limitMaxLength(workOrderInfo.getAlarmLocation(), true, 50, "报警位置不合法!");
        WJAssert.limitMaxLength(workOrderInfo.getDeptName(), true, 50, "部门名称不合法!");
        WJAssert.limitMaxLength(workOrderInfo.getAcceptUserName(), true, 50, "接单人昵称不合法!");
        WJAssert.limitMaxLength(workOrderInfo.getOperator(), true, 100, "操作人不合法!");
        WJAssert.limitMaxLength(workOrderInfo.getRemark(), true, 255, "备注不合法!");
    }
}
